/*
 * @FileName: bsp_adc.c
 * @Author: GreyQiu qiushaogui@aikosolar.com
 * @Date: 2023-07-12 16:05:59
 * @LastEditors: GreyQiu qiushaogui@aikosolar.com
 * @LastEditTime: 2023-09-23 13:40:56
 * @Description: 
 * 
 * Copyright (c) 2023, All Rights Reserved. 
 */

#include "bsp_adc.h"
#include "bsp_gpio.h"
#include "bsp_pwm.h"
#include "loop.h"

volatile int16_t g_adcBuffer[ADC_INJECT_CH_NUM];

/**
 * @description: 配置ADC
 */
static void adc_config(void) {
    ADC_InitType ADC_InitStructure;

    /* ADC时钟配置 ------------------------------------------------*/
    RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_ADC);
    ADC_Clock_Mode_Config(ADC_CKMOD_AHB, RCC_ADCHCLK_DIV2); // AHB始终时钟128Mhz, 2分频后64Mhz给ADC
    RCC_ADC_1M_Clock_Config(RCC_ADC1MCLK_SRC_HSE, RCC_ADC1MCLK_DIV8);  //selsect HSE as RCC ADC1M CLK Sourced

    /* ADC configuration ------------------------------------------------------*/
    ADC_InitStructure.MultiChEn      = ENABLE;
    ADC_InitStructure.ContinueConvEn = DISABLE;
    ADC_InitStructure.ExtTrigSelect  = ADC_EXT_TRIGCONV_REGULAR_SWSTRRCH;
    ADC_InitStructure.DatAlign       = ADC_DAT_ALIGN_R;
    ADC_InitStructure.ChsNumber      = ADC_REGULAR_LEN_2; // 规则通道有外部温度和芯片温度2个
    ADC_Initializes(&ADC_InitStructure);


    /* 配置注入通道序列 */
    ADC_Injected_Channels_Number_Config(ADC_INJECTED_LEN_1);  // 4个注入通道

    ADC_Channel_Sample_Time_Config(BSP_ADC_CH_VAC, ADC_SAMPLE_TIME1);
    ADC_Injected_Sequence_Conversion_Number_Config(BSP_ADC_CH_VAC, ADC_CH_NUM_VAC);

    /* ADC injected external trigger configuration */
    ADC_Injected_Group_External_Trigger_Source_Config(ADC_EXT_TRIGCONV_INJECTED_T1_TRGO); // 注入通道转换触发源选择为TIM1 TRGO信号
    ADC_External_Trigger_Conversion_Config(ADC_EXTTRIGCONV_INJECTED_ENABLE); // 允许外部触发
    /* Disable automatic injected conversion start after regular one */
    ADC_Injected_Group_Autoconversion_Disable();
    /* Enable JEOC interrupt */
    ADC_Interrupts_Enable(ADC_INT_JENDC); // 注入序列转换结束，触发中断

    /* Enable ADC */
    ADC_ON();
    /* Check ADC Ready */
    while(ADC_Flag_Status_Get(ADC_RD_FLAG, ADC_FLAG_JENDCA, ADC_FLAG_RDY) == RESET);
    /* Start ADC calibration */
    ADC_Calibration_Operation(ADC_CALIBRATION_ENABLE);
    /* Check the end of ADC calibration */
    while (ADC_Calibration_Operation(ADC_CALIBRATION_STS));
}

/**
 * @description: 配置ADC的DMA传输
 */
static void adc_dma_config(void) {
//    DMA_InitType DMA_InitStructure;

//    RCC_AHB_Peripheral_Clock_Enable(RCC_AHB_PERIPH_DMA); // 使能DMA时钟
//    /* DMA Channel1 Configuration ----------------------------------------------*/
//    DMA_Reset(DMA_CH1);
//    DMA_InitStructure.PeriphAddr     = (uint32_t)&ADC->DAT;
//    DMA_InitStructure.MemAddr        = (uint32_t)g_adcTempBuffer;
//    DMA_InitStructure.Direction      = DMA_DIR_PERIPH_SRC;
//    DMA_InitStructure.BufSize        = ADC_REGULATE_CH_NUM;
//    DMA_InitStructure.PeriphInc      = DMA_PERIPH_INC_MODE_DISABLE;
//    DMA_InitStructure.MemoryInc      = DMA_MEM_INC_MODE_ENABLE;
//    DMA_InitStructure.PeriphDataSize = DMA_PERIPH_DATA_WIDTH_HALFWORD;
//    DMA_InitStructure.MemDataSize    = DMA_MEM_DATA_WIDTH_HALFWORD;
//    DMA_InitStructure.CircularMode   = DMA_CIRCULAR_MODE_ENABLE;
//    DMA_InitStructure.Priority       = DMA_CH_PRIORITY_HIGH;
//    DMA_InitStructure.Mem2Mem        = DMA_MEM2MEM_DISABLE;
//    DMA_Initializes(DMA_CH1, &DMA_InitStructure);
//    DMA_Channel_Request_Remap(DMA_CH1, DMA_REMAP_ADC);
//    // DMA_Interrupts_Enable(DMA_CH1, DMA_INT_TXC);
//    /* Enable DMA channel1 */
//    DMA_Channel_Enable(DMA_CH1);
}

/**
 * @description: 配置ADC中断
 */
static void adc_interrupt_config(void) {
    NVIC_InitType NVIC_InitStructure1;

    /* Configure and enable ADC interrupt */
    NVIC_InitStructure1.NVIC_IRQChannel                   = ADC_IRQn; // DMA_Channel1_IRQn;
    NVIC_InitStructure1.NVIC_IRQChannelPreemptionPriority = 0x00;
    NVIC_InitStructure1.NVIC_IRQChannelSubPriority        = 0x00;
    NVIC_InitStructure1.NVIC_IRQChannelCmd                = ENABLE;
    NVIC_Initializes(&NVIC_InitStructure1);
    NVIC_SetPriority(ADC_IRQn, NVIC_EncodePriority(NVIC_GetPriorityGrouping(), 0, 0));
}

/**
 * @description: 初始化ADC
 */
void bsp_adc_init(void) {
//    adc_dma_config();
    adc_config();
    adc_interrupt_config();
}

void DMA_Channel1_IRQHandler(void) {
    DMA_Interrupt_Status_Clear(DMA, DMA_CH1_INT_TXC);
}


/**
 * @description: 初始化ADC
 */
void bsp_adc_temp_trig(void)
{
    ADC->CTRL2 |= ADC_CTRL2_SWSTRRCH;
}

